package com.levi.service.impl;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.fasterxml.jackson.databind.ser.Serializers;
import com.levi.mapper.FlowableMapper;
import com.levi.service.FlowableService;
import com.levi.vo.TaskVO;
import org.flowable.bpmn.constants.BpmnXMLConstants;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.common.engine.impl.util.IoUtil;
import org.flowable.engine.*;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author shentong
 * @date 2021/8/16 16:24
 * @Description TODO
 */
@Service
public class FlowableServiceImpl implements FlowableService {
    @Resource
    private FlowableMapper flowableMapper;

    @Resource
    private ProcessEngine processEngine;

    @Autowired
    private TaskService taskService;

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private HistoryService historyService;

    @Autowired
    private FlowProcessDiagramGenerator flowProcessDiagramGenerator;

    @Override
    public String getTaskIdByUserAndBussinessId(String userName,String id) {
        return flowableMapper.getTaskIdByUserAndBussinessId(userName,id);
    }

    /**
     * 通过流程实例ID获取任务
     * @param processInstanceId
     * @return 任务列表
     * @Author shentong
     */
    @Override
    public List<Task> getTasksByProcessInstanceId(String processInstanceId) {

        List<Task> tasks = new ArrayList<>();
        tasks = processEngine.getTaskService().createTaskQuery().processInstanceId(processInstanceId).active().orderByTaskCreateTime().desc().list();
        return tasks;
    }

    @Override
    public List<TaskVO> getApplyingTask(String userName) {
        return flowableMapper.getApplyingTask(userName);
    }

    @Override
    public List<TaskVO> getApplyedTasks(String userName) {
        return flowableMapper.getApplyedTasks(userName);
    }

    @Override
    public byte[] createImage(String processInstanceId) {
        //1.获取当前的流程实例
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
        String processDefinitionId = null;
        List<String> activeActivityIds = new ArrayList<>();
        List<String> highLightedFlows = new ArrayList<>();
        //2.获取所有的历史轨迹线对象
        List<HistoricActivityInstance> historicSquenceFlows = historyService.createHistoricActivityInstanceQuery()
                .processInstanceId(processInstanceId).activityType(BpmnXMLConstants.ELEMENT_SEQUENCE_FLOW).list();
        historicSquenceFlows.forEach(historicActivityInstance -> highLightedFlows.add(historicActivityInstance.getActivityId()));
        //3. 获取流程定义id和高亮的节点id
        if (processInstance != null) {
            //3.1. 正在运行的流程实例
            processDefinitionId = processInstance.getProcessDefinitionId();
            activeActivityIds = runtimeService.getActiveActivityIds(processInstanceId);
        } else {
            //3.2. 已经结束的流程实例
            HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
            processDefinitionId = historicProcessInstance.getProcessDefinitionId();
            //3.3. 获取结束节点列表
            List<HistoricActivityInstance> historicEnds = historyService.createHistoricActivityInstanceQuery()
                    .processInstanceId(processInstanceId).activityType(BpmnXMLConstants.ELEMENT_EVENT_END).list();
            List<String> finalActiveActivityIds = activeActivityIds;
            historicEnds.forEach(historicActivityInstance -> finalActiveActivityIds.add(historicActivityInstance.getActivityId()));
        }
        //4. 获取bpmnModel对象
        BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
        //5. 生成图片流
        InputStream inputStream = flowProcessDiagramGenerator.generateDiagram(bpmnModel, activeActivityIds, highLightedFlows);
        //6. 转化成byte便于网络传输
        return IoUtil.readInputStream(inputStream, "image inputStream name");
    }

}
